﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MoneyManagerNET.Infrastructure
{
    public class CovariantWrapper<TInterface, TImplementation> : ICollection<TInterface> where TImplementation : TInterface
    {
        ICollection<TImplementation> uniderlying_collection;
        public CovariantWrapper(ICollection<TImplementation> collection)
        {
            this.uniderlying_collection = collection;
        }

        public void Add(TInterface item)
        {
            var c = (TImplementation)item;
            this.uniderlying_collection.Add(c);
        }

        public void Clear()
        {
            this.uniderlying_collection.Clear();
        }

        public bool Contains(TInterface item)
        {
            return this.uniderlying_collection.Contains((TImplementation)item);
        }

        public void CopyTo(TInterface[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public int Count
        {
            get { return this.uniderlying_collection.Count; }
        }

        public bool IsReadOnly
        {
            get { return uniderlying_collection.IsReadOnly; }
        }

        public bool Remove(TInterface item)
        {
            return this.uniderlying_collection.Remove((TImplementation)item);
        }

        public IEnumerator<TInterface> GetEnumerator()
        {
            return new CovariantEnmerator<TInterface,TImplementation>(this.uniderlying_collection.GetEnumerator());
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

    }

    public class CovariantEnmerator<TInterface, TImplementation> : IEnumerator<TInterface> where TImplementation:TInterface {

        IEnumerator<TImplementation> underlyin_implementation;

        public CovariantEnmerator(IEnumerator<TImplementation>  e)
        {
            this.underlyin_implementation = e;
        }

        public TInterface Current
        {
            get { return (TInterface)this.underlyin_implementation.Current; }
        }

        public void Dispose()
        {
            this.underlyin_implementation.Dispose();
        }

        object System.Collections.IEnumerator.Current
        {
            get { return this.underlyin_implementation.Current; }
        }

        public bool MoveNext()
        {
            return this.underlyin_implementation.MoveNext();
        }

        public void Reset()
        {
            this.underlyin_implementation.Reset();
        }
    }
}
